#include"paral_py_ast.h"

// 定义一个函数初始化
void init_ast_tree_construct_context(struct ast_tree_construct_context* ast_ctx, std::vector<struct paral_py_tok_basic_info> expression){
    // 用一个要分析的语句来初始化
    ast_ctx->expression = expression;
    ast_ctx->expression_index = 0;

    ast_ctx->trans_result_str = "";

    ast_ctx->related_to_result_assign = false;

    // 如果当前语句开头是result等于，那么说明这是result的赋值语句
    if(expression.size()>=2){
        // 开头是result
        if(expression[0].tok_str.find("result[") == 0){
            // 开头是result
            // 第二个是等号
            if(expression[1].tok_str == "="){
                ast_ctx->related_to_result_assign = true;
            }
        }
    }

    // 现有eof初始化语法树的根部
    ast_ctx->tree_root = NULL;
}

struct paral_py_tok_basic_info get_next_tok_basic_info(struct ast_tree_construct_context* ast_ctx){
    struct paral_py_tok_basic_info return_info;
    
    // 获取一个
    if(ast_ctx->expression_index < ast_ctx->expression.size()){
        return_info = ast_ctx->expression[ast_ctx->expression_index];
        ast_ctx->expression_index = ast_ctx->expression_index + 1;
        return return_info;
    }else{
        return_info.paral_py_token_type = paral_py_language_tok_eof;
        return return_info;
    }
}

struct paral_py_tok_basic_info get_current_tok_basic_info(struct ast_tree_construct_context *ast_ctx)
{
    
    struct paral_py_tok_basic_info return_info;

    if (ast_ctx->expression_index == 0)
    {
        return_info.paral_py_token_type = paral_py_language_tok_unknow;
        return return_info;
    }
    else if ((ast_ctx->expression_index - 1) > (ast_ctx->expression.size() - 1))
    {
        return_info.paral_py_token_type = paral_py_language_tok_eof;
        return return_info;
    }
    else
    {
        return_info = ast_ctx->expression[ast_ctx->expression_index - 1];
        return return_info;
    }
}

// 预处理在需要的位置插入占位符
void ast_tree_construct_prepare(struct ast_tree_construct_context* ast_ctx){
    // 要插入的
    struct paral_py_tok_basic_info insert_info;
    insert_info.paral_py_token_type = paral_py_language_tok_var;
    insert_info.tok_str = "None";
    
    // 遍历已有的数组，找到以上几种情况
    // op出现在头部或者末尾
    // 两个op相邻
    // op左边是左括号，或者右边是右括号
    int i;
    for(i = 0; i < ast_ctx->expression.size(); i++){
        // 开头op
        if(i == 0 && ast_ctx->expression[i].paral_py_token_type == paral_py_language_tok_op){
            // 开头插入占位符
            ast_ctx->expression.insert(ast_ctx->expression.begin(), insert_info);
            continue;
        }

        // 结尾op
        if(i ==(ast_ctx->expression.size() - 1)&& ast_ctx->expression[i].paral_py_token_type == paral_py_language_tok_op){
            ast_ctx->expression.push_back(insert_info);
            continue;
        }

        // 如果是一个op，那看看下一个op，两个之间插入占位符
        if(ast_ctx->expression[i].paral_py_token_type == paral_py_language_tok_op && ast_ctx->expression[i+1].paral_py_token_type == paral_py_language_tok_op){
            ast_ctx->expression.insert(ast_ctx->expression.begin()+i+1, insert_info);
            continue;
        }

        // 左括号和op合起来
        if(ast_ctx->expression[i].tok_str == "(" && ast_ctx->expression[i+1].paral_py_token_type == paral_py_language_tok_op){
            
            ast_ctx->expression.insert(ast_ctx->expression.begin()+i+1, insert_info);
            continue;
        }

        // op和右括号
        if(ast_ctx->expression[i].paral_py_token_type == paral_py_language_tok_op && ast_ctx->expression[i+1].tok_str == ")"){
            ast_ctx->expression.insert(ast_ctx->expression.begin()+i+1, insert_info);
            continue;
        }
    }

    // 完成
    // 在最后补一个eof
    insert_info.paral_py_token_type = paral_py_language_tok_eof;
    ast_ctx->expression.push_back(insert_info);
}

// 处理入口
void ast_tree_construct(struct ast_tree_construct_context* ast_ctx){
    // 首先获取一个语元
    struct paral_py_tok_basic_info token = get_next_tok_basic_info(ast_ctx);
    // 然后处理一个基本语元
    if(token.paral_py_token_type == paral_py_language_tok_eof){
        printf("empty code_line\n");
    }

    // 处理表达式
    ast_ctx->tree_root = parse_express_element(ast_ctx);
}

// 处理表达式
struct ast_tree_node* parse_express_element(struct ast_tree_construct_context* ast_ctx){
    // 首先处理基本语元
    struct ast_tree_node* LHS = parse_primary_element(ast_ctx);
    if(LHS == NULL){
        return NULL;
    }

    // 变量的优先级是0
    return parse_op_element(ast_ctx, LHS, 0);
}

// 处理基本语元
struct ast_tree_node* parse_primary_element(struct ast_tree_construct_context* ast_ctx){
    // 查看当前的语元
    struct paral_py_tok_basic_info token = get_current_tok_basic_info(ast_ctx);
    
    // print_paral_py_tok_basic_info(token);

    // 看看当前语元是什么
    if(token.tok_str == "("){
        return parse_paren_element(ast_ctx);
    }

    if(token.paral_py_token_type == paral_py_language_tok_var){

        // 处理变量
        return parse_var_element(ast_ctx);
    }

    // 如果都不是，那就是未知基本语元
    printf("not a primary token\n");

    exit(-1);

    return NULL;
}

// 处理变量
struct ast_tree_node* parse_var_element(struct ast_tree_construct_context* ast_ctx){

    // 这行代码非常重要，C++11中不需要struct标识符了，并且通过直接new才能调用结构体中元素的构造函数
    struct ast_tree_node *return_node = new ast_tree_node;

    return_node->left = NULL;
    return_node->right = NULL;

    std::string str = get_current_tok_basic_info(ast_ctx).tok_str;

    return_node->token_str = str;

    return_node->paral_py_token_type = get_current_tok_basic_info(ast_ctx).paral_py_token_type;

    return_node->left = NULL;

    return_node->right = NULL;

    // 吃掉当前token
    get_next_tok_basic_info(ast_ctx);

    // 返回
    return return_node;
}

// 处理括号
struct ast_tree_node* parse_paren_element(struct ast_tree_construct_context* ast_ctx){
    // 吃掉括号
    get_next_tok_basic_info(ast_ctx);
    // 处理表达式
    struct ast_tree_node* return_ast = parse_express_element(ast_ctx);

    if(return_ast == NULL){
        return NULL;
    }

    // 查看当前是不是括号
    if(get_current_tok_basic_info(ast_ctx).tok_str != ")"){
        printf("without )\n");
        exit(-1);
    }

    // 吃掉右括号
    get_next_tok_basic_info(ast_ctx);

    return return_ast;
}

int prinp_of_cur_token(struct ast_tree_construct_context* ast_ctx){
    // 获取当前元素
    struct paral_py_tok_basic_info info = get_current_tok_basic_info(ast_ctx);
    
    // 根据内容确定优先级
    if(get_current_tok_basic_info(ast_ctx).tok_str == "="){
        return 1;
    }else if(get_current_tok_basic_info(ast_ctx).paral_py_token_type == paral_py_language_tok_op){
        return 2;
    }else if(get_current_tok_basic_info(ast_ctx).paral_py_token_type == paral_py_language_tok_var){
        return 0;
    }else{
        return -1;
    }
}


// 处理二元表达式
struct ast_tree_node* parse_op_element(struct ast_tree_construct_context* ast_ctx, ast_tree_node* LHS, int last_prinp){
    
    // 二元表达式是一串的
    while(1){
        int cur_prinp = prinp_of_cur_token(ast_ctx);

        // 当前优先级比之前的优先级高，说明传入的LHS是自己的左子树
        // 如果优先级比之前的低，说明传入的LHS是别人的右子树

        // std::cout << cur_prinp << "," << last_prinp << std::endl;
        // print_paral_py_tok_basic_info(get_current_tok_basic_info(ast_ctx));

        if(cur_prinp < last_prinp){
            
            // 直接返回
            // 除了正常的解析，可以用用作结束的用途，因为eof的优先级最低
            return LHS;
        }

        // 构建当前的ast节点
        struct ast_tree_node* node = new ast_tree_node;
        node->paral_py_token_type = get_current_tok_basic_info(ast_ctx).paral_py_token_type;
        node->token_str = get_current_tok_basic_info(ast_ctx).tok_str;

        // 吃掉当前op
        get_next_tok_basic_info(ast_ctx);

        // 解析下一个基本元素，获得操作符的右半部分
        struct ast_tree_node* RHS = parse_primary_element(ast_ctx);

        // std::cout << "----" << RHS->token_str << std::endl;

        // 没有右子树是有问题
        if(RHS == NULL){
            printf("op without RHS\n");
            exit(-1);
        }

        // 获取下一个节点的优先级
        int next_prinp = prinp_of_cur_token(ast_ctx);

        // 如果下一个运算符的优先级比当前运算符高，前面解析出的RHS就是下一个运算符的LHS
        if(cur_prinp<next_prinp){
            RHS = parse_op_element(ast_ctx, RHS, cur_prinp);
            if(RHS == NULL){
                return NULL;
            }
        }

        // 这里说明当前的优先级都不比前后小
        // 这里说明优先级最大的
        node->left = LHS;
        node->right = RHS;
        LHS = node;
    }
}

void print_ast_tree(struct ast_tree_node* root){

    if(root == NULL){
        return;
    }

    // 打印
    print_token_of_input_paral_fun_MR(root->paral_py_token_type);
    std::cout << " @ " << root->token_str << std::endl;
    
    // 打印左边和右边
    print_ast_tree(root->left);
    print_ast_tree(root->right);
}


std::string trans_ast_to_str(struct ast_tree_node* root){
    // 使用中序遍历的方式
    std::string result_str = "";
    if(root == NULL){
        return result_str;
    }
    
    // 变量、调用、等号的处理是不一样的。
    if(root->paral_py_token_type == paral_py_language_tok_var){
        // 对于变量就直接返回
        result_str = root->token_str;
        return result_str;
    }

    // 调用
    if(root->paral_py_token_type == paral_py_language_tok_op && root->token_str != "="){
        result_str = root->token_str;
        result_str = result_str + "(";
        result_str = result_str + trans_ast_to_str(root->left);
        result_str = result_str + ",";
        result_str = result_str + trans_ast_to_str(root->right);
        result_str = result_str + ")";
        return result_str;
    }

    // 等号
    if(root->paral_py_token_type == paral_py_language_tok_op && root->token_str == "="){
        
        result_str = result_str + trans_ast_to_str(root->left);
        
        result_str = result_str + "=";
        
        result_str = result_str + trans_ast_to_str(root->right);
        return result_str;
    }

    // 不可能到这里
    std::cout<< "impossiable to reach" << std::endl;
    return "";
}